<template>
  <div>
    <div class="user-header">
      <a-form
          layout="inline"
          :model="searchState"
          @finish="searchFinish"
      >
        <a-form-item v-bind="validateInfos.username" label="用户名">
          <a-input v-model:value="searchState.username" placeholder="请输入查询的名称"/>
        </a-form-item>
        <a-form-item>
          <a-button
              type="primary"
              html-type="submit"
              style="margin-right: 10px"
          >
            查询
          </a-button>
          <a-button
              style="margin-right: 10px"
              type="primary"
              @click="resetFields"
          >
            重置
          </a-button>
          <a-button
              type="primary"
              @click="createClick"
          >
            新建
          </a-button>
        </a-form-item>
      </a-form>
    </div>
    <a-table :dataSource="dataSource" :columns="columns" bordered :pagination="pagination">
      <template #bodyCell="{column,record}">
        <template v-if="column.key === 'action'">
          <a-button type="primary" style="margin-right: 10px" @click="editClick(record)">编辑</a-button>
          <a-popconfirm
              :title="'是否确定删除'+record.username+'用戶?'"
              ok-text="确定"
              cancel-text="取消"
              @confirm="delClick(record.id)"
          >
            <a-button type="primary" danger>删除</a-button>
          </a-popconfirm>
        </template>
      </template>
    </a-table>
  </div>
  <a-modal :visible="modalState.visible" :title="modalState.title" :footer="null"
           @cancel="()=>modalState.visible=false">
    <a-form :model="userState" @finish="userFinish">
      <a-form-item label="名称" v-bind="userValidateInfos.username">
        <a-input v-model:value="userState.username"/>
      </a-form-item>
      <a-form-item v-if="!currentData" label="密码" v-bind="userValidateInfos.password">
        <a-input-password v-model:value="userState.password"/>
      </a-form-item>
      <a-form-item label="权限" v-bind="userValidateInfos.jurisdiction">
        <a-checkbox-group v-model:value="userState.jurisdiction">
          <a-checkbox :value="item.id" v-for="item in jurisdictionData">{{ item.name }}</a-checkbox>
        </a-checkbox-group>
      </a-form-item>
      <a-form-item style="" :wrapper-col="{ offset: 7 }">
        <a-button type="primary" html-type="submit">提交</a-button>
        <a-button style="margin-left: 10px" @click="resetUserFields">重置</a-button>
      </a-form-item>
    </a-form>
  </a-modal>
</template>
<script setup lang="ts">
import {onMounted, reactive, ref, toRaw, watchEffect} from "vue";
import {createUser, delUser, editUser, jurisdictionList, userList} from "@/api/api";
import type {AxiosResponse} from "axios";
import {message} from "ant-design-vue";
import type {JurisdictionType, MetaType, ModalType, UserBodyType} from "@/util/publicType";
import moment from "moment";
import {useForm} from "ant-design-vue/es/form";
import {ColumnsType} from "ant-design-vue/es/table";

// 表格type
interface DataType {
  id: string,
  username: string,
  jurisdictions: Array<{
    id: string,
    name: string,
    english_name: string,
  }>,
  created_at: number | string,
}

// 搜索参数类型
interface FormState {
  username: string;
}

// 页数
const page = ref<number>(1);

// 每页条数
const size = ref<number>(15);

// 搜索参数
const username = ref<string | null>(null);

// 数据
const dataSource = ref<DataType[]>([]);

// 当前操作数据
const currentData = ref<DataType | null>(null);

// 对话框相关
const modalState = reactive<ModalType>({
  visible: false,
  title: "新建用户",
});

// 权限列表
const jurisdictionData = ref<JurisdictionType[]>([]);

// 查询表单初始值
const searchState = reactive<FormState>({
  username: '',
});

// 添加用户表单初始值
const userState = reactive<UserBodyType>({
  username: '',
  password: '',
  jurisdiction: []
})

// 搜索參數字段校验
const searchRuleRef = reactive({
  username: [
    {
      required: false,
    }
  ],
})

// 用戶参数字典校验
const userRuleRef = reactive({
  username: [
    {
      required: true,
      message: "请输入你的用户名"
    }
  ],
  password: [
    {
      required: true,
      message: "请输入你的密码"
    }
  ],
  jurisdiction: [
    {
      required: true,
      message: "至少选择一项权限"
    }
  ]

})

// 获取搜索参数表单事件
const {resetFields, validate, validateInfos} = useForm(searchState, searchRuleRef);
// 获取用户表单数据
const resetUserFields = useForm(userState, userRuleRef).resetFields;
const userValidate = useForm(userState, userRuleRef).validate;
const userValidateInfos = useForm(userState, userRuleRef).validateInfos;
// 分页
const pagination = ref({
  total: 0,
  current: page.value,
  // 默认每页显示条数
  defaultPageSize: page.value,
  // 每页条数
  pageSize: size,
  // 是否快速跳转
  showQuickJumper: true,
  // 是否可以改变pagesize
  showSizeChanger: true,
  // 总条数
  showTotal: (total: number) => "总条数：" + total,
  //页码改变或者条数的回调
  onChange: (p: number, ps: number) => {
    page.value = p;
    size.value = ps;
  },
});

// 表头
const columns: ColumnsType<DataType> = [
  {
    title: '姓名',
    dataIndex: 'username',
    key: 'username',
    align: "center",
  },
  {
    title: '创建时间',
    dataIndex: 'created_at',
    key: 'created_at',
    align: "center",
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    align: "center",
  },
];

// 请求
const getData = (page: number, username: string | null = null) => {
  userList(page, size.value, username).then((r: AxiosResponse) => {
    let data: DataType[] = r.data.data.data;
    const meta: MetaType = r.data.data.meta;
    data = data.map(v => {
      return {
        ...v,
        created_at: moment((v.created_at as number) * 1000).format("YYYY-MM-DD HH:mm:ss")
      }
    })
    dataSource.value = data;
    // 分页器
    pagination.value = {
      ...pagination.value,
      pageSize: meta.perSize,
      total: meta.total,
      current: meta.currentPage,
    };
  }, err => message.error(err))
}

// 侦听page、size以及搜索参数的变化（赋值后，前后无变化，不执行）
watchEffect(() => {
  getData(page.value, username.value);
});

// DOM已挂载
onMounted(() => {
// 加载权限
  jurisdictionList().then((r: AxiosResponse) => {
    const {data} = r.data.data;
    jurisdictionData.value = data;
  }, err => message.error(err))
});

// 编辑
const editClick = (v: DataType) => {
  currentData.value = v;
  modalState.title = "编辑用户";
  modalState.visible = true;
  userState.username = v.username;
  userState.jurisdiction = v.jurisdictions.map(v => v.id);
  userState.password = '不告诉你';
}

// 新建
const createClick = () => {
  currentData.value = null;
  modalState.visible = true;
  modalState.title = "新建用户"
}

// 删除
const delClick = (v: string) => {
  delUser(v).then(() => {
    message.success("删除成功");
    getData(page.value, username.value);
  })
}

// 搜索
const searchFinish = () => {
  validate().then(() => {
    const name = toRaw(searchState).username;
    if (!name) {
      username.value = null;
    } else {
      username.value = name;
    }
  })
}

// 用户表单完成
const userFinish = () => {
  let request: Promise<AxiosResponse>;
  userValidate().then(() => {
    const data = toRaw(userState);
    if (currentData.value) {
      request = editUser({username: data.username, jurisdiction: data.jurisdiction}, currentData?.value?.id as string);
    } else {
      request = createUser(data);
    }
    request.then(async (r: AxiosResponse) => {
      modalState.visible = false;
      resetUserFields();
      getData(page.value, username.value);
      await message.success("操作成功");
      if (currentData.value) {
        window.location.reload();
      }
    }, err => message.error(err))
  })
}
</script>

<style scoped lang="less">
.user-header {
  margin: 30px 0;
}
</style>